package fengcan;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

import org.apache.commons.codec.binary.Hex;

import Entity.WcsDvcEntity;
import log.WcsLog;
import utils.ExecutorUnits;
import utils.LogUnits;
import utils.PropertiesUnits;

/**
 * 建立每个单独的socket的线程
 * @author 风蚕
 *
 */
class SocketThread extends Thread{
	private WcsLog logger;
	
	private WcsDvcEntity wcs;
	private String ip;
	private int port;
	private String msgStart;//报文头
	private String msgEnd;//报文尾
	private boolean isLive = false;//socket是否连接
	private StringBuffer suffix = new StringBuffer();//一次is流中最后一个完整报文后的报文
	
	private int bufferSize;
	public SocketThread(WcsDvcEntity wcs) {
		this.wcs = wcs;
		this.ip = wcs.getDvcIp();
		this.port = Integer.valueOf(wcs.getPort());
		this.msgStart = wcs.getRevBegin();
		this.msgEnd = wcs.getRevEnd();
		this.logger = LogUnits.getLogger(SocketThread.class, wcs);
		this.bufferSize = Integer.valueOf(PropertiesUnits.getPropertiesMap().get("bytes"));//从属性文件中得到的每次读取的字节数
		
	}

	
//	@SuppressWarnings({ "resource", "unused" })//socket、io未关闭会产生警告信息
	@Override
//	@SneakyThrows
	public void run() {
		Socket socket = null;
		InputStream is = null;
		OutputStream os = null;
		while(true){
			//创建socket
			while(!isLive) {
				try {
//					LogUnits.infoMoreLog("开始与"+ip+":"+port+",创建连接。。。");
					logger.info("开始与"+ip+":"+port+",创建连接。。。");
					socket = new Socket(ip,port);
					isLive = true;
				} catch (Exception e) {
//					LogUnits.infoMoreLog("与"+ip+":"+port+"创建socket连接失败！");
					logger.info("与"+ip+":"+port+"创建socket连接失败！");
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e1) {
						e1.printStackTrace();
					}
				}
			}
			
			try {
				is = socket.getInputStream();
				os = socket.getOutputStream();
//				LogUnits.infoMoreLog("连接建立。。。。");
				logger.info("与"+ip+":"+port+",连接成功！！");
				int length = -1;
				//接收从is中读取的字节数组
	            byte[] receiveBytes = new byte[bufferSize];
	            while((length = is.read(receiveBytes)) != -1) {
	            	//存放去除多余零后的字节数组
					byte[] cutZeroBytes = new byte[length];
//					System.out.println("bytsLength:"+cutZeroBytes.length);
					/*
	            	 * 无法确定socket服务端发送的具体报文大小，字节数组必须尽可能的大。因此字节数组末尾会产生多余的0。
	            	 */
					//字节数组去零
					System.arraycopy(receiveBytes, 0, cutZeroBytes, 0, length);
					String receiveHexStr = Hex.encodeHexString(cutZeroBytes).toUpperCase();//字节数组转大写16进制
					
					//分析报文
					receiveHexStr = analyzeMsg(receiveHexStr);
					//这里调用存储过程
//					System.out.println("suffix:"+suffix.toString());
//					System.out.println("result:"+receiveHexStr);
					
					if (!"".equals(receiveHexStr)) {
//						System.out.println("调用存储过程。。。");
						Thread runThread = new ProduceThread(wcs, os, receiveHexStr);
						//线程池里调用线程
						ExecutorUnits.getExecutor().execute(runThread);
					}
				

					receiveBytes = new byte[bufferSize];
	            }
//	            System.out.println("读取结束！！");
				socket.close();
			} catch (Exception e) {
				e.printStackTrace();
//				LogUnits.errorLog(ip+":"+port+"的socket: 发生错误，错误信息："+e.getMessage());
				logger.error(ip+":"+port+"的socket: 发生错误，错误信息："+e.getMessage());
			}finally {
				try {
					socket.close();
					isLive = false;
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * Ps:通过上一次留下的报文suffix和接收的报文，判断报文的完整程度
	 * @param msg
	 * @return
	 */
	public String analyzeMsg(String msg) {
		String receiveHexStr = msg;
		/*
		 *对接收报文的处理逻辑：
		 *1、如果该报文是个首尾完整的报文，直接传入储存过程，然后把suffix设置为空。 
		 *2、如果该报文有头无尾，则把suffix设置为空，然后把报文存储到suffix里。
		 *3、如果该报文无头有尾，先查看suffix是否为空，不为空，拼接后报文，传入存储过程；为空，丢弃报文。
		 *4、如果该报文件无头无尾，先查看suffix是否为空，不为空，拼接报文，保存；为空，丢弃报文。
		 *总结：逻辑保证suffix里存储的报文数据为空或是有头无尾的状态。
		 */
		if(receiveHexStr.startsWith(msgStart) && receiveHexStr.endsWith(msgEnd)) {
//			System.out.println("有头有尾");
			//一个完整报文
			suffix.setLength(0); //清空
		}else if(receiveHexStr.startsWith(msgStart) && !receiveHexStr.endsWith(msgEnd)) {
//			System.out.println("有头无尾");
			suffix.setLength(0);
			suffix.append(receiveHexStr);
			receiveHexStr = "";
		}else if(!receiveHexStr.startsWith(msgStart) && receiveHexStr.endsWith(msgEnd)) {
//			System.out.println("无头有尾");
			if ("".equals(suffix.toString())) {
				receiveHexStr = "";
			}else {
				//一个完整报文
				receiveHexStr = suffix.append(receiveHexStr).toString();
				suffix.setLength(0);
			}
		}else {
//			System.out.println("无头无尾");
			if(!"".equals(suffix.toString())) {
				receiveHexStr = suffix.append(receiveHexStr).toString();
			}
			receiveHexStr = "";
		}
		
		return receiveHexStr;
	}


}